home *** CD-ROM | disk | FTP | other *** search
/ Sprite 1984 - 1993 / Sprite 1984 - 1993.iso / src / machserver / 1.098 / fsutil / fsutilNotify.c < prev    next >
C/C++ Source or Header  |  1990-10-10  |  8KB  |  298 lines

  1. /* 
  2.  * fsNotify.c --
  3.  *
  4.  * Routines to handle notification of processes waiting on handles.
  5.  * Each handle has a few "wait lists" associated with it that contain
  6.  * state for each process waiting on a file, each list is for a different
  7.  * kind of waiter, ie. readers, writers, lockers.  Processes get stuck into
  8.  * these wait lists when an operation on the file would block for some reason.
  9.  * When the file unblocks, there are other routines to call to notify all
  10.  * the processes that have been added to the waiting lists.
  11.  *
  12.  * Copyright (C) 1986 Regents of the University of California
  13.  * All rights reserved.
  14.  */
  15.  
  16. #ifndef lint
  17. static char rcsid[] = "$Header: /sprite/src/kernel/fsutil/RCS/fsutilNotify.c,v 9.1 90/10/08 13:18:17 mendel Exp $ SPRITE (Berkeley)";
  18. #endif not lint
  19.  
  20.  
  21. #include <sprite.h>
  22. #include <fs.h>
  23. #include <fsutil.h>
  24. #include <fsNameOps.h>
  25. #include <proc.h>
  26. #include <sync.h>
  27. #include <rpc.h>
  28. #include <net.h>
  29.  
  30. #include <stdio.h>
  31.  
  32. static Sync_Lock notifyLock = Sync_LockInitStatic("Fs:notifyLock");
  33. #define LOCKPTR (¬ifyLock)
  34.  
  35.  
  36. /*
  37.  *----------------------------------------------------------------------
  38.  *
  39.  * Fsutil_WaitListInsert --
  40.  *
  41.  *    Add a process to a list of waiters.  This handles the case where
  42.  *    the process is already on the list.
  43.  *
  44.  * Results:
  45.  *    None
  46.  *
  47.  * Side effects:
  48.  *    Calls malloc and adds to the list.
  49.  *
  50.  *----------------------------------------------------------------------
  51.  */
  52.  
  53. ENTRY void
  54. Fsutil_WaitListInsert(list, waitPtr)
  55.     List_Links *list;        /* List to add waiter to */
  56.     Sync_RemoteWaiter *waitPtr;    /* Info about process for remote waiting */
  57. {
  58.     register Sync_RemoteWaiter *myWaitPtr;
  59.  
  60.     LOCK_MONITOR;
  61.  
  62.     LIST_FORALL(list, (List_Links *) myWaitPtr) {
  63.     /*
  64.      * If already on list then update wait token.
  65.      */
  66.     if (myWaitPtr->pid == waitPtr->pid &&
  67.         myWaitPtr->hostID == waitPtr->hostID) {
  68.         myWaitPtr->waitToken = waitPtr->waitToken;
  69.         UNLOCK_MONITOR;
  70.         return;
  71.     }
  72.     }
  73.  
  74.     /*
  75.      * Not on the list so put it there.
  76.      */
  77.  
  78.     myWaitPtr = (Sync_RemoteWaiter *) malloc(sizeof(Sync_RemoteWaiter));
  79.     *myWaitPtr = *waitPtr;
  80.     List_Insert((List_Links *)myWaitPtr, LIST_ATREAR(list));
  81.  
  82.     UNLOCK_MONITOR;
  83. }
  84.  
  85. /*
  86.  *----------------------------------------------------------------------
  87.  *
  88.  * Fsutil_FastWaitListInsert --
  89.  *
  90.  *    An un-monitored version of Fsutil_WaitListInsert that depends
  91.  *    on handle locking, or something, by higher levels for
  92.  *    synchronization.  Note: the malloc is needed because
  93.  *    of select.  Regular read and write use a Sync_RemoteWaiter
  94.  *    struct declared in Fs_Read or Fs_Write, and it won't go
  95.  *    away while the pipe reader or writer waits.  However, with
  96.  *    select the waiter might go away before we notify it, so
  97.  *    we have to malloc and copy the wait structure.
  98.  *
  99.  * Results:
  100.  *    None
  101.  *
  102.  * Side effects:
  103.  *    Calls malloc and adds to the list.
  104.  *
  105.  *----------------------------------------------------------------------
  106.  */
  107.  
  108. ENTRY void
  109. Fsutil_FastWaitListInsert(list, waitPtr)
  110.     List_Links *list;        /* List to add waiter to */
  111.     Sync_RemoteWaiter *waitPtr;    /* Info about process for remote waiting */
  112. {
  113.     register Sync_RemoteWaiter *myWaitPtr;
  114.  
  115.     LIST_FORALL(list, (List_Links *) myWaitPtr) {
  116.     /*
  117.      * If already on list then update wait token.
  118.      */
  119.     if (myWaitPtr->pid == waitPtr->pid &&
  120.         myWaitPtr->hostID == waitPtr->hostID) {
  121.         myWaitPtr->waitToken = waitPtr->waitToken;
  122.         return;
  123.     }
  124.     }
  125.  
  126.     /*
  127.      * Not on the list so put it there.
  128.      */
  129.  
  130.     myWaitPtr = (Sync_RemoteWaiter *) malloc(sizeof(Sync_RemoteWaiter));
  131.     *myWaitPtr = *waitPtr;
  132.     List_Insert((List_Links *)myWaitPtr, LIST_ATREAR(list));
  133. }
  134.  
  135. /*
  136.  *----------------------------------------------------------------------
  137.  *
  138.  * Fsutil_WaitListNotify --
  139.  *
  140.  *      Notify all the processes in a wait-list.  If the process is on a
  141.  *      remote host then an RPC is done to that host.
  142.  *
  143.  * Results:
  144.  *    None
  145.  *
  146.  * Side effects:
  147.  *      This results in a call to Sync_ProcWakeup on the host of the
  148.  *      waiting process.  The list is emptied with each item being freed
  149.  *      with free.
  150.  *
  151.  *----------------------------------------------------------------------
  152.  */
  153.  
  154. ENTRY void
  155. Fsutil_WaitListNotify(list)
  156.     register List_Links *list;    /* List of waiting processes to notify */
  157. {
  158.     register Sync_RemoteWaiter *waitPtr;
  159.  
  160.     LOCK_MONITOR;
  161.     while ( ! List_IsEmpty(list)) {
  162.     waitPtr = (Sync_RemoteWaiter *)List_First(list);
  163.     if (waitPtr->hostID != rpc_SpriteID) {
  164.         /*
  165.          * Contact the remote host and get it to notify the waiter.
  166.          */
  167.         if (waitPtr->hostID > NET_NUM_SPRITE_HOSTS) {
  168.         printf( "Fsutil_WaitListNotify bad hostID %d.\n",
  169.               waitPtr->hostID);
  170.         } else {
  171.         (void)Sync_RemoteNotify(waitPtr);
  172.         }
  173.     } else {
  174.         /*
  175.          * Mark the local process as runable.
  176.          */
  177.         Sync_ProcWakeup(waitPtr->pid, waitPtr->waitToken);
  178.     }
  179.     List_Remove((List_Links *)waitPtr);
  180.     free((Address)waitPtr);
  181.     }
  182.     UNLOCK_MONITOR;
  183. }
  184.  
  185. /*
  186.  *----------------------------------------------------------------------
  187.  *
  188.  * Fsutil_FastWaitListNotify --
  189.  *
  190.  *      A faster version of Fsutil_WaitListNotify that depends on higher
  191.  *    level synchronization like handle locking.
  192.  *
  193.  * Results:
  194.  *    None
  195.  *
  196.  * Side effects:
  197.  *      This results in a call to Sync_ProcWakeup on the host of the
  198.  *      waiting process.  The list is emptied with each item being freed
  199.  *      with free.
  200.  *
  201.  *----------------------------------------------------------------------
  202.  */
  203.  
  204. ENTRY void
  205. Fsutil_FastWaitListNotify(list)
  206.     register List_Links *list;    /* List of waiting processes to notify */
  207. {
  208.     register Sync_RemoteWaiter *waitPtr;
  209.  
  210.     while ( ! List_IsEmpty(list)) {
  211.     waitPtr = (Sync_RemoteWaiter *)List_First(list);
  212.     if (waitPtr->hostID != rpc_SpriteID) {
  213.         /*
  214.          * Contact the remote host and get it to notify the waiter.
  215.          */
  216.         (void)Sync_RemoteNotify(waitPtr);
  217.     } else {
  218.         /*
  219.          * Mark the local process as runable.
  220.          */
  221.         Sync_ProcWakeup(waitPtr->pid, waitPtr->waitToken);
  222.     }
  223.     List_Remove((List_Links *)waitPtr);
  224.     free((Address)waitPtr);
  225.     }
  226. }
  227.  
  228.  
  229. /*
  230.  *----------------------------------------------------------------------
  231.  *
  232.  * Fsutil_WaitListRemove --
  233.  *
  234.  *    Remove a process from the list of waiters.
  235.  *
  236.  * Results:
  237.  *    None
  238.  *
  239.  * Side effects:
  240.  *    Calls free and deletes from the list.
  241.  *
  242.  *----------------------------------------------------------------------
  243.  */
  244.  
  245. ENTRY void
  246. Fsutil_WaitListRemove(list, waitPtr)
  247.     List_Links *list;        /* List to remove waiter from. */
  248.     Sync_RemoteWaiter *waitPtr;    /* Info about process for remote waiting */
  249. {
  250.     register Sync_RemoteWaiter *myWaitPtr;
  251.     register Sync_RemoteWaiter *nextPtr;
  252.  
  253.     LOCK_MONITOR;
  254.  
  255.     nextPtr = (Sync_RemoteWaiter *) List_First(list);
  256.     while (! List_IsAtEnd(list, (List_Links *)nextPtr) ) {
  257.     myWaitPtr = nextPtr;
  258.     nextPtr = (Sync_RemoteWaiter *)List_Next((List_Links *)myWaitPtr);
  259.     if (myWaitPtr->pid == waitPtr->pid &&
  260.         myWaitPtr->hostID == waitPtr->hostID) {
  261.         List_Remove((List_Links *) myWaitPtr);
  262.         free((Address) myWaitPtr);
  263.     }
  264.     }
  265.     UNLOCK_MONITOR;
  266. }
  267.  
  268. /*
  269.  *----------------------------------------------------------------------
  270.  *
  271.  * Fsutil_WaitListDelete --
  272.  *
  273.  *    Delete and Free all entries from a wait list.  This is used
  274.  *    when removing handles.
  275.  *
  276.  * Results:
  277.  *    None
  278.  *
  279.  * Side effects:
  280.  *    Calls free and deletes from the list.
  281.  *
  282.  *----------------------------------------------------------------------
  283.  */
  284.  
  285. ENTRY void
  286. Fsutil_WaitListDelete(list)
  287.     List_Links *list;        /* List to clean up. */
  288. {
  289.     register Sync_RemoteWaiter *myWaitPtr;
  290.  
  291.     while (!List_IsEmpty(list)) {
  292.     myWaitPtr = (Sync_RemoteWaiter *)List_First(list);
  293.     List_Remove((List_Links *) myWaitPtr);
  294.     free((Address) myWaitPtr);
  295.     }
  296. }
  297.  
  298.